iT邦幫忙

2024 iThome 鐵人賽

DAY 6
0
Software Development

微服務奇兵:30天Quarkus特訓營系列 第 6

Groovy 語法簡易介紹 與 Gradle 相關設定檔案

  • 分享至 

  • xImage
  •  

Groovy 語法簡易介紹

Groovy 是一種動態語言,可以用於開發完整的應用程式,但在 Gradle 中,我們主要將其用於管理套件和建置專案。以下我們將針對在 Java 中使用 Gradle 進行相依套件管理與專案建置時常用的語法進行說明。

1. 變數與資料型態

Groovy 是一個動態類型語言

  • 使用 def 關鍵字定義變數。Groovy 會根據賦值自動推斷類型。
  • 賦值不強制指定資料型別,但也可以明確指定類型。

def projectName = "Quarkus App"
int version = 1

注意: 雖然 Groovy 是動態類型語言,但它與 Java 兼容,因此你仍然可以使用 Java 的強類型語法。

2. 函數與閉包(Closure)

Groovy 中最強大的語法之一是閉包(Closure)。閉包是一段可執行的程式碼塊,可以在任意位置定義並傳遞作為參數。在 Gradle 中,閉包被廣泛用於配置區塊。

基本語法:

def greet = { name ->
    println "Hello, $name"
}

greet("Quarkus")

Gradle中的閉包範例:

task hello {
    doLast {
        println 'Hello from Groovy Closure in Gradle!'
    }
}

這裡的 doLast 就是一個閉包,它定義了在任務完成時需要執行的代碼。

對於閉包想更理解的話,可以參考我之前寫的文章 FP(Functional programming)簡易釐清 (含Currying 與 Closure 理解

3. 集合(List 和 Map)

Groovy 提供了簡化的集合處理方式,這對於在 Gradle 腳本中管理依賴列表或其他項目設定很有用。

  • List:有序集合,可以包含重複元素。
  • Map:鍵值對集合,用於存儲與查找。

範例:

def dependencies = ['quarkus-resteasy', 'quarkus-hibernate-orm']
dependencies.each { dep ->
    println "Adding dependency: $dep"
}

def config = [name: 'Quarkus', version: '2.8.1']
println "Project ${config.name} version ${config.version}"

4. 字串插值與操作

Groovy 允許簡單的字串插值,這在 Gradle 腳本中非常有用。例如,插入變數到字串中使用 $ 符號。

範例:

def version = '1.0'
println "Building project version $version"

多行字串:Groovy 支援使用三引號(''')來定義多行字串:

def description = '''
This is a multi-line
string in Groovy
'''
println description

5. 條件語句與迴圈

Groovy 支援 Java 標準的 if-else 條件語句和各種迴圈,但它也提供了更簡潔的語法來進行條件判斷和迭代。

  • 條件語句:
if (project.hasProperty('env')) {
    println "Environment: ${project.env}"
} else {
    println "No environment specified."
}
  • 迴圈:Groovy 提供了多種簡單的迭代方式。例如,each 方法可以輕鬆遍歷列表:
def tasks = ['compile', 'test', 'deploy']
tasks.each { task ->
    println "Executing task: $task"
}

6. 安全呼叫運算子**(Safe Navigation Operator)**

在 Groovy 中,使用 ?. 可以防止 NullPointerException,如果左側變數為 null,則整個表達式結果為 null,不會引發錯誤。

範例:

def person = null
println person?.name  // 不會引發 NullPointerException

7. Gradle DSL 與 Groovy 的結合

Gradle 腳本實際上就是 Groovy 代碼。在 Gradle 中,幾乎所有構建腳本中的語法都是基於 Groovy 的 DSL 語法,例如:

  • apply plugin: 'java'
  • repositories { mavenCentral() }
  • dependencies { implementation 'io.quarkus:quarkus-resteasy' }

這些語法實際上就是 Groovy 的閉包結構。閉包允許你輕鬆定義並修改 Gradle 中的各種配置。

Gradle 專案設定檔案介紹

Gradle 主要是執行相關的 Groovy 程式,通過這些程式來下載 Maven 的套件或執行編譯相關的指令,以達到客製化與控管專案的套件與編譯執行。在 Gradle 專案中,主要有三個關鍵的設定檔案:gradle.propertiessettings.gradlebuild.gradle。讓我們逐一介紹它們的用途和常見設定:

gradle.properties

gradle.properties 用於定義全局變數和屬性,主要用於定義可在多個腳本中重用的屬性。這對於大型專案中特別有用,因為它提供了一種集中管理變數的方式,避免在多個地方重複定義相同的值。

常見用途:

  • 配置全域變數:在大型專案中,某些值,如版本號、依賴的組件名稱等,可能在多個地方使用。gradle.properties 提供了定義這些值的集中位置。
  • 設置 Gradle 執行行為:你可以通過設定各種參數來優化 Gradle 的性能,例如併發構建、增量構建和緩存配置等。
  • 存儲敏感信息:如 API 密鑰或數據庫憑證。這些變數不應直接包含在版本控制中,建議通過環境變量或安全的管理系統來處理。
# Plugin 版本管理
quarkusPluginId=io.quarkus
quarkusPluginVersion=2.8.1.Final

# 平台 BOM 定義
quarkusPlatformGroupId=io.quarkus.platform
quarkusPlatformArtifactId=quarkus-bom
quarkusPlatformVersion=2.8.1.Final

# 優化構建性能
org.gradle.daemon=true       # 開啟 Gradle Daemon 加速構建
org.gradle.parallel=true     # 允許並行構建
org.gradle.caching=true      # 啟用構建緩存

這樣的設置文件可以在 build.gradle 中直接引用變數,如:

plugins {
    id "${quarkusPluginId}" version "${quarkusPluginVersion}"
}

settings.gradle

settings.gradle 文件是專案的入口點,用來定義專案的基本設置和結構。它負責告訴 Gradle 哪些模組(子專案)屬於該構建的一部分,並可配置依賴解析方式和套件管理。

常見用途:

  • 定義多模組專案:通過 include 語法來聲明專案中的各個子模組,使 Gradle 可以將它們納入構建流程。
  • 套件管理pluginManagement 區塊用來集中管理 Gradle 插件,包括定義套件的版本號和存儲庫位置,這有助於保持套件版本的一致性。
  • 依賴解析配置:可以指定專案的依賴解析策略,如使用中央存儲庫(如 Maven Central)或者企業內部的私有存儲庫。
// 定義根專案名稱
rootProject.name = 'my-quarkus-project'

// 定義子專案
include 'api', 'service', 'domain'

// 套件管理
pluginManagement {
    repositories {
        mavenCentral()
        gradlePluginPortal()
    }
    plugins {
        id "${quarkusPluginId}" version "${quarkusPluginVersion}"
    }
}

// 依賴版本管理
dependencyResolutionManagement {
    repositories {
        mavenCentral()
    }
    versionCatalogs {
        libs {
            version('junit', '5.8.2')
            library('junit-api', 'org.junit.jupiter', 'junit-jupiter-api').versionRef('junit')
            library('junit-engine', 'org.junit.jupiter', 'junit-jupiter-engine').versionRef('junit')
        }
    }
}

SubProject 設定與管理

在大型專案中,通常會有多個子模組,每個模組負責不同的功能或領域。這些模組可以共享某些配置,也可以有專屬的設置。

子模組結構範例

my-project/
|-- settings.gradle
|-- build.gradle
|-- api/
|   |-- build.gradle
|-- service/
    |-- build.gradle

settings.gradle 文件中通過 include 命令來定義這些子專案:

rootProject.name = 'my-project'
include 'api', 'service'

api/build.gradle

plugins {
    id 'java'
}

dependencies {
    implementation 'io.quarkus:quarkus-resteasy'
}

service/build.gradle

plugins {
    id 'java'
}

dependencies {
    implementation 'org.hibernate:hibernate-core:5.4.30.Final'
}

這樣,Gradle 會將 apiservice 模組納入專案的構建中,並可以在它們各自的 build.gradle 文件中進行具體的配置。

build.gradle

build.gradle 是 Gradle 的核心構建腳本,每個專案或子專案都會有一個 build.gradle 文件。這個文件負責定義構建邏輯、依賴管理和自定義任務。

用途:

  • 套件應用與配置:Gradle 套件能夠擴展構建腳本的功能,如應用 Java 插件來構建 Java 專案。
  • 依賴管理:在 dependencies 區塊中聲明專案的各種依賴,包括編譯時依賴、運行時依賴、測試依賴等。
  • 自定義任務:使用 Groovy 或 Kotlin 定義自定義任務,這些任務可以是複雜的編譯邏輯、測試邏輯或部署步驟。

配置範例

// 針對所有專案的通用配置
allprojects {
    apply plugin: 'java'

    group = 'com.example'
    version = '1.0.0-SNAPSHOT'

    sourceCompatibility = '11'
    targetCompatibility = '11'
    
    repositories {
        mavenCentral()
    }
}

// 針對子專案的通用依賴配置
subprojects {
    dependencies {
        testImplementation 'junit:junit:4.13'
    }

    test {
        useJUnitPlatform()
    }
}

// 根專案的特定依賴
dependencies {
    implementation 'org.apache.commons:commons-lang3:3.12.0'
}

// 自定義任務
task hello {
    doLast {
        println 'Hello from root project'
    }
}

子專案的 build.gradle 範例:

plugins {
    id 'io.quarkus'
}

dependencies {
    implementation 'io.quarkus:quarkus-resteasy'
    // 子專案特定的依賴
}

// 定義子專案的自定義任務
task buildApi {
    doLast {
        println 'Building API module...'
    }
}


上一篇
BasicGradle 介紹
下一篇
GraalVM快速理解-關於JVM
系列文
微服務奇兵:30天Quarkus特訓營7
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言